//
//  UIViewController+LBRouter.m
//  LBRouter
//
//  Created by WuShiHai on 19/5/24.
//  Copyright (c) 2019 Lebbay. All rights reserved.
//

#import "UIViewController+LBRouter.h"
#import <LBFoundation/LBFoundation.h>
#import <LBUIKit/LBUIKit.h>
#import "LBRouterHandler.h"
#import "LBRouterConfigurationHeader.h"

@interface LBRouterFadePushAnimator : NSObject<UIViewControllerAnimatedTransitioning>

@end

@implementation LBRouterFadePushAnimator

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
    return 0.3;
}

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
    UIView *to = [transitionContext viewForKey:UITransitionContextToViewKey];
    if (to) {
        [transitionContext.containerView addSubview:to];
        to.alpha = 0;

        NSTimeInterval duration = [self transitionDuration:transitionContext];
        [UIView animateWithDuration:duration
                         animations:^{
            to.alpha = 1;
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:!transitionContext.transitionWasCancelled];
        }];
    }
}

@end

@implementation UIViewController (Router)

+ (NSString *)routerWithParameters:(NSDictionary *)parameters{    
    NSString *router = [LBRouterHandler routerWithNativeClass:[self class]];
    if (router) {
        if (router) {
            NSString *URLString = router;
            
            if ([self respondsToSelector:@selector(needLogin)]) {
                BOOL needLogin = ((BOOL (*)(id, SEL))[self methodForSelector:@selector(needLogin)])(self, @selector(needLogin));
                if (needLogin) {
                    NSMutableDictionary *tokenMutableDictionary = [@{} mutableCopy];
                    [tokenMutableDictionary setObject:@"!" forKey:@"token"];
                    [tokenMutableDictionary addEntriesFromDictionary:parameters];
                    parameters = [tokenMutableDictionary copy];
                }
            }
            
            URLString = [[URLString componentsSeparatedByString:@"?"] firstObject];
            NSString *scheme = LBBundleConfigureStringValue(LBRouterServiceConfiguration, LBRouterServiceAppSchemeName, @"router");
            NSString *schemeString = [NSString stringWithFormat:@"%@://com.lebbay.native.router", scheme];
            NSURL *URL = [[NSURL alloc] initWithString:schemeString];
            NSString *parametersString = [NSString stringWithFormat:@"?%@", [parameters URLParamterString]?:@""];
            NSURL *RouterURL = [[NSURL alloc] initWithString:router relativeToURL:URL];
            return [RouterURL.absoluteString stringByAppendingString:parametersString];
        }else{
            NSAssert(NO, @"未找到Controller匹配的Router，请确认对应的Controller调用了LB_REGISTER_CONTROLLER_ROUTER()方法");
        }
    }
    
    return nil;
}

- (instancetype)initWithURL:(NSString *)URLString
                   userInfo:(NSDictionary *)userInfo{
    if (self = [self init]) {
        self.URLString = URLString;
        self.userInfo = userInfo;
        [self matchRouterPropertyWithUserInfo:userInfo];
    }
    return self;
}

- (void)matchRouterPropertyWithUserInfo:(NSDictionary *)userInfo{
    SEL selector = NSSelectorFromString(@"LB_ROUTER_PROPERTY_AUTO_MATCH");
    if ([[self class] respondsToSelector:selector]) {
        NSArray<NSString *> *array = ((NSArray * (*)(id, SEL))[[self class] methodForSelector:selector])([self class], selector);
        [self matchRouterPropertyWithUserInfo:userInfo array:array];
    }
}

- (void)matchRouterPropertyWithUserInfo:(NSDictionary *)userInfo array:(NSArray *)array{
    if ([array isKindOfClass:[NSArray class]]) {
        NSMutableDictionary *parameters = [@{} mutableCopy];
        [array enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([obj isKindOfClass:[NSString class]] && [userInfo.allKeys containsObject:obj]) {
                [parameters setObject:[userInfo objectForKey:obj] forKey:obj];
            }
        }];
        [self yy_modelSetWithDictionary:parameters];
    }
}

+ (BOOL)isOpenWithPush {
    return YES;
}

+ (UIViewController *)presentedNavigationController:(UIViewController *)vc {
    return [[LBNavigationController alloc] initWithRootViewController:vc];
}

- (void)setURLString:(NSString *)URLString{
    objc_setAssociatedObject(self, _cmd, URLString, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSString *)URLString{
    return objc_getAssociatedObject(self, @selector(setURLString:));
}

- (void)setUserInfo:(NSDictionary *)userInfo{
    objc_setAssociatedObject(self, _cmd, userInfo, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (NSDictionary *)userInfo{
    return objc_getAssociatedObject(self, @selector(setUserInfo:));

}

#pragma mark - UINavigationControllerDelegate
- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                            animationControllerForOperation:(UINavigationControllerOperation)operation
                                                         fromViewController:(UIViewController *)fromVC
                                                           toViewController:(UIViewController *)toVC {
    NSDictionary *userInfo = toVC.userInfo;
    NSUInteger openStyle = [[userInfo objectForKey:@"openStyle"] integerValue];
    switch (operation) {
        case UINavigationControllerOperationPush:
            if (openStyle == 3) {
                return [[LBRouterFadePushAnimator alloc] init];
            }
            break;
        default:
            break;
    }
    return nil;
}

@end
